package discovery

import (
	"errors"
	"fmt"

	"github.com/didi/nightingale/src/toolkits/i18n"
)

var (
	discoveries    = map[string]Discovery{}
	errUnsupported = errors.New("unsupported")
)

type Category string

// Discovery is an abstract, pluggable interface for monapi & phomethues service discovery.
type Discovery interface {
	// Name return the discovery name
	Name() string
	// Get return a discovery by collectRule.Id
	Get(id int64) (interface{}, error)
	// Gets return discovery list by node ids
	Gets(nids []int64) ([]interface{}, error)
	// GetByNameAndNid return discovery by discovery.Name & discovery.Nid
	GetByNameAndNid(name string, nid int64) (interface{}, error)
	// GetsUnCorrelate return unCorrelate discovery
	GetsUnCorrelate(nids []int64) ([]interface{}, error)
	// Create a discovery by []byte format, witch could be able to unmarshal with a discovery struct
	Create(data []byte, username string) error
	// Update a discovery by []byte format, witch could be able to unmarshal with a discovery struct
	Update(data []byte, username string) error
	// Delete a discovery by discovery.Id with operator's name
	Delete(id int64, username string) error
	// Template return a template used for UI render
	Template() (interface{}, error)
}

func DiscoveryRegister(d Discovery) error {
	name := d.Name()
	if _, ok := discoveries[name]; ok {
		return fmt.Errorf("collector %s exists", name)
	}
	discoveries[name] = d

	return nil
}

func GetDiscovery(name string) (Discovery, error) {
	if c, ok := discoveries[name]; !ok {
		return nil, fmt.Errorf("collector %s does not exist", name)
	} else {
		return c, nil
	}
}

func _s(format string, a ...interface{}) string {
	return i18n.Sprintf(format, a...)
}

func DisplayDiscovery() {
	fmt.Println(discoveries)
	for name, _ := range discoveries {
		fmt.Println(name)
	}
}
